package yxk.report.wtc.wtte;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.ILocaleString;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.BasedataEntityType;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.datamodel.events.BeforeSetItemValueEventArgs;
import kd.bos.entity.datamodel.events.ChangeData;
import kd.bos.entity.datamodel.events.IDataModelChangeListener;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.entity.property.BasedataProp;
import kd.bos.entity.property.MulBasedataProp;
import kd.bos.form.container.Tab;
import kd.bos.form.control.events.TabSelectEvent;
import kd.bos.form.control.events.TabSelectListener;
import kd.bos.form.field.BasedataEdit;
import kd.bos.form.field.DateEdit;
import kd.bos.form.field.events.AfterBindingDataEvent;
import kd.bos.form.field.events.BasedataEditListener;
import kd.bos.form.mcontrol.mobtable.MobTable;
import kd.bos.form.mcontrol.mobtable.events.IBeforeCreateMobTableColumnsListener;
import kd.bos.form.plugin.AbstractMobFormPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import yxk.utils.DateUtil;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 人员考勤报表
 */
public class AttendanceInformatioReport extends AbstractMobFormPlugin implements IBeforeCreateMobTableColumnsListener, TabSelectListener,BasedataEditListener, IDataModelChangeListener{
    private SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
    private SimpleDateFormat time=new SimpleDateFormat("HH:mm:ss");

    public void registerListener (EventObject e){
    // 页签添加监听事件*
        Tab tab = this.getView().getControl("nwg5_tabap");
        tab.addTabSelectListener(this);
        BasedataEdit personid = this.getControl("nwg5_personid");
        BasedataEdit user = this.getControl("nwg5_user");
        user.addBasedataEditListener(this);
        personid.addBasedataEditListener(this);
    }

    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        String key = e.getProperty().getName();
        IDataModel model = this.getModel();
        ChangeData[] changeSet = e.getChangeSet();
        ChangeData changeData = changeSet[0];
        if("nwg5_startdate".equals(key)){
            Object endDate = model.getValue("nwg5_enddate");
            if(changeData.getNewValue() !=null && endDate != null){
                Date end= (Date) endDate;
                Date start= (Date) changeData.getNewValue();
                if (start.getTime() <= end.getTime()) {
                    DynamicObjectCollection nwg5Personid = (DynamicObjectCollection) model.getValue("nwg5_personid");
                    executeMobTableAdd((Date) changeData.getNewValue(), (Date) endDate, nwg5Personid,key ,"nwg5_mobtableap");
                }else{
                    model.setValue("nwg5_enddate",start);
                }
            }
        }else if("nwg5_enddate".equals(key)){
            Object startdate = model.getValue("nwg5_startdate");
            if(startdate != null && changeData.getNewValue() != null) {
                Date start= (Date) startdate;
                Date end= (Date) changeData.getNewValue();
                if (start.getTime() <= end.getTime()) {
                    DynamicObjectCollection nwg5Personid = (DynamicObjectCollection) model.getValue("nwg5_personid");
                    executeMobTableAdd(start, end, nwg5Personid, key,"nwg5_mobtableap");
                }else{
                    model.setValue("nwg5_startdate",end);
                }
            }
        }else if("nwg5_personid".equals(key)){
            Object startdate = model.getValue("nwg5_startdate");
            Object endDate = model.getValue("nwg5_enddate");
            if(endDate !=null && startdate != null){
                executeMobTableAdd((Date)startdate,(Date)endDate,(DynamicObjectCollection)changeData.getNewValue(),key ,"nwg5_mobtableap");
            }
        }else if("startdate".equals(key)){
            Object endDate = model.getValue("enddate");
            if(changeData.getNewValue() !=null && endDate != null){
                Date end= (Date) endDate;
                Date start= (Date) changeData.getNewValue();
                if (start.getTime() <= end.getTime()) {
                    DynamicObjectCollection nwg5Personid = (DynamicObjectCollection) model.getValue("nwg5_user");
                    executeMobTableAdd((Date) changeData.getNewValue(), (Date) endDate, nwg5Personid,key ,"mobtableap");
                }else{
                    model.setValue("enddate",start);
                }
            }
        }else if("enddate".equals(key)){
            Object startdate = model.getValue("startdate");
            if(startdate != null && changeData.getNewValue() != null) {
                Date start= (Date) startdate;
                Date end= (Date) changeData.getNewValue();
                if (start.getTime() <= end.getTime()) {
                    DynamicObjectCollection nwg5Personid = (DynamicObjectCollection) model.getValue("nwg5_user");
                    executeMobTableAdd(start, end, nwg5Personid, key,"mobtableap");
                }else{
                    model.setValue("startdate",end);
                }
            }
        }else if("nwg5_user".equals(key)){
            Object startdate = model.getValue("startdate");
            Object endDate = model.getValue("enddate");
            if(endDate !=null && startdate != null){
                executeMobTableAdd((Date)startdate,(Date)endDate,(DynamicObjectCollection)changeData.getNewValue(),key ,"mobtableap");
            }
        }
    }

    /**
     *
     * @param startDate       查询开始时间
     * @param endDate         查询结束时间
     * @param nwg5Personid    人员集合
     * @param key             操作编码
     * @param tabpageap       移动表格标识
     */
    private void  executeMobTableAdd(Date startDate,Date endDate,DynamicObjectCollection nwg5Personid,String key,String tabpageap){
        if(startDate != null || endDate != null){
            //如果人员为空就获取直接下属
            Boolean ean = false;
            if(nwg5Personid == null || nwg5Personid.size()==0){
                nwg5Personid = userDirectReports();
                if(nwg5Personid == null || nwg5Personid.size() == 0){
                    this.getView().updateView("mobtableap");
                    return;
                }
                ean=true;
            }
            DynamicObjectCollection collection = numberQueryAttendPerson(nwg5Personid, ean);
            if(collection != null && collection.size() > 0) {
                switch (key) {
                    case "nwg5_startdate":
                    case "nwg5_enddate":
                    case "nwg5_personid":
                        Map<String, Map<String, Map<String, String>>> map = changedDateQuery( startDate,  endDate, collection);
                        addText(tabpageap, map, null, "1");
                        break;
                    case "startdate":
                    case "enddate":
                    case "nwg5_user":
                        Map<String, Map<String, List<Map<String, String>>>> maps = changedMulticardQuery(startDate, endDate, collection);
                        addText(tabpageap, null, maps, "0");
                        break;
                }
                this.getView().updateView(tabpageap);
            }

        }
    }


    @Override
    public void beforeBindData(EventObject e) {
        //设置时间可选范围
        DateEdit nwg5_startdate= this.getControl("nwg5_startdate");
        nwg5_startdate.setMaxDate(new Date());
        DateEdit nwg5_enddate= this.getControl("nwg5_enddate");
        nwg5_enddate.setMaxDate(new Date());
        DateEdit startdate= this.getControl("startdate");
        startdate.setMaxDate(new Date());
        DateEdit enddate= this.getControl("enddate");
        enddate.setMaxDate(new Date());

        BasedataEdit edit = this.getControl("nwg5_personid");
        edit.setDisplayProp("person.name");
        Date day = DateUtil.MonthAdd(new Date(), Calendar.DATE, -1);
        this.getModel().setValue("nwg5_startdate",day);
        this.getModel().setValue("nwg5_enddate",day);
        //获取下级任职经历
        DynamicObjectCollection collection = userDirectReports();
        if(collection != null && collection.size() > 0) {
            //根据任职经历获取考勤人员信息
            DynamicObjectCollection coll = numberQueryAttendPerson(collection,true);
            if(coll != null && coll.size() > 0) {
                addText("nwg5_mobtableap", changedDateQuery(day, day, coll), null, "1");
            }
        }
    }

    /**
     *  考勤异常
     * @param startDate     开始时间
     * @param endDate       结束时间
     * @param collection    人员集合
     * @return
     */
    private Map<String,Map<String,Map<String,String>>> changedDateQuery(Date startDate, Date endDate, DynamicObjectCollection collection){
       QFilter qF=new QFilter("owndate", QCP.large_equals,startDate)
               .and("owndate",QCP.less_equals,endDate);
        if(collection != null && collection.size()>0){
            List<Long> list=new ArrayList<>();
            for (DynamicObject row : collection) {
                String pkID = row.getPkValue().toString();
                list.add(Long.parseLong(pkID));
            }
            qF.and("personid",QCP.in,list);
        }

       DynamicObject[] attrecordBases = BusinessDataServiceHelper.load("wtdtd_attrecordbase", "id,personid,dateattr,owndate,attfileid,attfilevid", qF.toArray());
       List<Long> attIds=new ArrayList<>();
       for (DynamicObject rowAtt : attrecordBases) {
           attIds.add(Long.parseLong(rowAtt.getPkValue().toString()));
       }

       DynamicObject[] loaded = BusinessDataServiceHelper.load("wtdtd_attrecorddetail", "attmain,attitemid,fattitemid,owndate,valuestring",
               new QFilter("attmain", QCP.in, attIds)
                       .and(new QFilter("attitemid.number",QCP.in,new String[]{"EX_1010_S","OR_1030_S","OR_1040_S","EX_1020_S","RE_1030_S","EX_1140_S"})).toArray(),"attmain.personid asc,owndate desc");
       Map<String,Map<String,Map<String,String>>> exceMap=new HashMap<>();
       for (DynamicObject row : loaded) {
           String number = row.getString("attmain.personid.number");//人员编码
           String owndate = format.format(row.getDate("owndate"));//归属日期
           Map<String, Map<String,String>> personMap = exceMap.get(number);
           Map<String,String> map;
           if(personMap == null){
               personMap =new HashMap<>();
               map = new HashMap<>();
           }else{
               map = personMap.get(owndate);
               if( map == null ){
                   map = new HashMap<>();
               }
           }
           String name = row.getString("attmain.personid.name");//人员工号

           map.put("name",name);//姓名
           map.put("recordDate",owndate);//归属日期

           String exceTypeNumber = row.getString("attitemid.number");//考勤项目编码
           String value = row.getString("valuestring");
           String typeNumber = map.get(exceTypeNumber);
           if(typeNumber != null){
               BigDecimal big=new BigDecimal(typeNumber);
               big=big.add(new BigDecimal(value)).setScale(2,BigDecimal.ROUND_HALF_UP);
               map.put(exceTypeNumber, big.toString());
           }else {
               map.put(exceTypeNumber, value);
           }
           personMap.put(owndate,map);
           exceMap.put(number,personMap);
       }
       return exceMap;
   }


    /**
     *  打卡数据
     * @param startDate     开始时间
     * @param endDate       结束时间
     * @param collection    人员集合
     * @return
     */
   private Map<String,Map<String,List<Map<String, String>>>> changedMulticardQuery(Date startDate, Date endDate, DynamicObjectCollection collection){
       QFilter qF=new QFilter("shiftdate", QCP.large_equals,startDate)
               .and("shiftdate",QCP.less_equals,endDate);
       if(collection != null && collection.size()>0){
           List<Long> list=new ArrayList<>();
           for (DynamicObject row : collection) {
               String pkID = row.getPkValue().toString();
               list.add(Long.parseLong(pkID));
           }
           qF.and("attperson",QCP.in,list);
       }
       DynamicObject[] multicards = BusinessDataServiceHelper.load("wtpm_multicard", "shiftdate,entryentity,attperson,mustpoint,effectivepoint", qF.toArray());
       Map<String,Map<String,List<Map<String, String>>>> map=new HashMap<>();

       for (DynamicObject multicard : multicards) {
           String number = multicard.getString("attperson.number");//人员工号
           Map<String, List<Map<String, String>>> multicardMap = map.get(number);
           List<Map<String, String>> mapList=new ArrayList<>();
           String shiftdate = format.format(multicard.getDate("shiftdate"));
           if( multicardMap == null ) {
               multicardMap = new HashMap<>();
           }
           //获取多次卡分录
           DynamicObjectCollection entryentity = multicard.getDynamicObjectCollection("entryentity");
           for (DynamicObject row : entryentity) {
               Map<String, String> mapRow = new HashMap<>();
               mapRow.put("attperson",multicard.getString("attperson.name"));//人员名称
               Date mustpoint = row.getDate("mustpoint");
               if(mustpoint != null) {
                   mapRow.put("mustpoint", time.format(mustpoint) );//应打卡点
               }
               Date effectivepoint = row.getDate("effectivepoint");
               if(effectivepoint != null) {
                   mapRow.put("effectivepoint", time.format(effectivepoint) );//有效打卡
               }
               mapList.add(mapRow);
           }
           multicardMap.put(shiftdate,mapList);
           map.put(number,multicardMap);
       }
        return map;
   }

    public void addText(String key, Map<String,Map<String,Map<String,String>>> exceMap,Map<String, Map<String, List<Map<String, String>>>> maps, String bleap) {
        MobTable mobTable = getControl(key);
        if("1".equals(bleap)){
            mobTable.addMobTablePackageDataHandlerListener(new AttendanceInformatioMobTableAdd(exceMap,bleap));
        } else if ("0".equals(bleap)) {
            mobTable.addMobTablePackageDataHandlerListener(new AttendanceInformatioMobTableAdd(bleap,maps));
        }


    }


    @Override
    public void tabSelected(TabSelectEvent tab) {
        String tabKey = tab.getTabKey();
        if("nwg5_tabpageap1".equals(tabKey)){
            IDataModel model = this.getModel();
            Object startdate = model.getValue("startdate");
            Object enddate = model.getValue("enddate");
            if(startdate == null && enddate == null){
                Date day = DateUtil.MonthAdd(new Date(), Calendar.DATE, -1);
                model.beginInit();
                model.setValue("startdate",day);
                model.setValue("enddate",day);
                DynamicObjectCollection collection = userDirectReports();
                if(collection != null) {
                    DynamicObjectCollection coll = numberQueryAttendPerson(collection, true);
                    if(collection != null && collection.size() > 0) {
                        Map<String, Map<String, List<Map<String, String>>>> maps = changedMulticardQuery(day, day, coll);
                        addText("mobtableap", null, maps, "0");
                    }
                }
                this.getView().updateView("nwg5_tabpageap1");
                model.endInit();

            }
        }
    }

    /**
     * 根据任职经历获取考勤人员信息
     * @return collection  任职经历
     * @return boll         人员集合是否是多选基础资料 true=不是多选基础资料、false = 是多选基础资料
     */
    private DynamicObjectCollection numberQueryAttendPerson(DynamicObjectCollection collection,Boolean boll){
        if(collection != null && collection.size()>0){
            List<String> list=new ArrayList<>();
            for (DynamicObject row : collection) {
                String number;
                if(boll) {
                    number = row.getString("person.number");
                }else {
                    DynamicObject fbasedataid = row.getDynamicObject("fbasedataid");
                    number = fbasedataid.getString("person.number");
                }
                list.add(number);
            }
            QFilter qF=new QFilter("number",QCP.in,list);
            DynamicObject[] persons = BusinessDataServiceHelper.load("wtp_attendperson", "id", qF.toArray());
            DynamicObjectCollection col=new DynamicObjectCollection();
            for (int i = 0; i < persons.length; i++) {
                col.add(i,persons[i]);
            }
            return col;
        }
        return  null;
    }
    /**
     * 获取直接下属名单
     */
    private DynamicObjectCollection userDirectReports() {
        long currentUserId = UserServiceHelper.getCurrentUserId();
        DynamicObject bosUser = BusinessDataServiceHelper.loadSingle(currentUserId, "bos_user");
        DynamicObject attendPerson = BusinessDataServiceHelper.loadSingleFromCache("hrpi_empposorgrel", "id,person,position",
                new QFilter("person.number", QCP.equals, bosUser.getString("number")).toArray());
        if (attendPerson != null) {
            //获取任职经历中的岗位，根据岗位获取下级人员
            DynamicObject position = attendPerson.getDynamicObject("position");
            DynamicObject[] positionhr = BusinessDataServiceHelper.load("hbpm_positionhr", "id,parent",
                    new QFilter("parent", QCP.equals, position.getPkValue()).and("iscurrentversion", QCP.equals, true).toArray());
            List<Long> list = new ArrayList<>();
            for (DynamicObject row : positionhr) {
                list.add(Long.parseLong(row.getPkValue().toString()));
            }
            DynamicObject[] loaded = BusinessDataServiceHelper.load("hrpi_empposorgrel", "position,person",
                    new QFilter("position", QCP.in, list).and("iscurrentversion", QCP.equals, true).toArray());
            DynamicObjectCollection collection = new DynamicObjectCollection();
            for (int i = 0; i < loaded.length; i++) {
                collection.add(i, loaded[i]);
            }
            return collection;
        }
        return null;
    }

    @Override
    public void afterBindingData(AfterBindingDataEvent evt) {
        BasedataEdit edit = (BasedataEdit) evt.getSource();
        Object v = evt.getDataEntity();
        Object editSearchProp;
        Object displayProp = "";
        if (v == null) {
            return;
        }
        BasedataEntityType dt;
        if (((DynamicObject) v).getDataEntityType() instanceof BasedataEntityType) {
            dt = (BasedataEntityType) ((DynamicObject) v).getDataEntityType();
        } else {
            dt = (BasedataEntityType) ((BasedataProp) edit.getProperty()).getComplexType();
        }

        //获取数据包中的名称字段值
        String nameKey = dt.getNumberProperty();
        IDataEntityProperty p2 = dt.findProperty(nameKey);
        if (p2 != null) {
            displayProp = p2.getValueFast(v);
            if (displayProp instanceof ILocaleString) {
                displayProp = displayProp.toString();
            }
        }

        //动态修改多选基础资料的显示属性为名称(部门)
        if ("nwg5_personid".equals(edit.getKey()) || "nwg5_user".equals(edit.getKey())) {
            nameKey = "person";
        }
        IDataEntityProperty p4 = dt.findProperty(nameKey);
        if (p4 != null) {
            DynamicObject row=(DynamicObject)p4.getValueFast(v);
            String name = row.getString("name");
            displayProp = String.format("%s",name);
        }

        editSearchProp = getEditSearchProp(edit.getProperty());
        //编辑显示属性也同步修改
        if (StringUtils.isNotBlank(editSearchProp)) {
            editSearchProp = editSearchProp.toString().replace("number", displayProp == null ? "" : displayProp.toString());
        }
        //设置显示属性
        evt.setDisplayProp(displayProp.toString());
        //设置编辑显示属性
        evt.setEditSearchProp(editSearchProp == null ? "" : editSearchProp.toString());
    }

    /**
     * 反解析选择的数据，并设置过滤条件
     *
     * @param e
     */
    @Override
    public void beforeSetItemValue(BeforeSetItemValueEventArgs e) {
        Object value = e.getValue();
        if (value == null) {
            return;
        }
        String searchKey = null;
        IDataEntityProperty property = e.getProperty();
        if ("nwg5_personid".equals(property.getName()) || "nwg5_user".equals(property.getName())) {
            searchKey = "person.name";
        }
        if (StringUtils.isBlank(searchKey)) {
            return;
        }
        String[] split = value.toString().split(",|;");
        String[] qfliterArr = new String[split.length];
        for (int i = 0; i < split.length; i++) {
            qfliterArr[i] = split[i].split("[( )]")[0];
        }
        //设置查询的字段
        e.setSearchKey(searchKey);
        //设置查询的数据
        e.setSearchArgs(qfliterArr);
    }

    /**
     * 获取配置的编辑显示属性
     *
     * @param property
     * @return
     */
    private String getEditSearchProp(IDataEntityProperty property) {
        BasedataProp basedataProp = null;
        if ((property instanceof BasedataProp)) {
            basedataProp = (BasedataProp) property;
        } else if (property instanceof MulBasedataProp) {
            basedataProp = (BasedataProp) ((MulBasedataProp) property).getRefBaseProp();
        }

        return basedataProp.getEditSearchProp();
    }

}
